﻿using Jst.Application.Contracts.IApplication.DbFirst;
using Jst.Core;
using Jst.Core.jwt;
using SqlSugar;
using System.Text;

namespace Jst.Application.DbFirst
{
    public class DbFirstServices : IDbFirstServices
    {

        private readonly DbManager _dbManager;

        public DbFirstServices(DbManager dbManager)
        {

            _dbManager = dbManager;
        }
        private ISqlSugarClient DbBaseClient => _dbManager.DefaultDb;

        /// <summary>
        /// 实体生成
        /// </summary>
        /// <param name="AClassName"></param>
        /// <returns></returns>
        public async Task<ApiResult> DbFirstAsync(string className)
        {
            var result = new ApiResult();

            if (await InsertDbFirstAsync(className)
                && await GenerateRepository(className)
                && await GenerateIRepository(className))
                return result.SuccessResult();
            return result.FailedResult(200, "操作失败");
        }

        #region DbFirst 实体

        public async Task<bool> InsertDbFirstAsync(string className)
        {
            string outputPath = "F:\\DbFirst生成\\Jst.Domain"; // 指定输出目录
                                                             // 检查目录是否存在，如果不存在则创建
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            string namespaceName = "Jst.Domain";   // 指定命名空间

            // 获取所有表信息
            var tableInfoList = DbBaseClient.DbMaintenance.GetTableInfoList();
            var dbTableInfo = tableInfoList.FirstOrDefault(t => t.Name == className);
            if (dbTableInfo == null)
            {
                return false;
            }

            // 获取列信息
            var columns = DbBaseClient.DbMaintenance.GetColumnInfosByTableName(className);

            // 生成类文件内容
            var classContent = new StringBuilder();
            classContent.AppendLine($"using System;");
            classContent.AppendLine($"using System.ComponentModel.DataAnnotations;");
            classContent.AppendLine($"using SqlSugar;");
            classContent.AppendLine($"namespace {namespaceName}");
            classContent.AppendLine("{");
            classContent.AppendLine($"    [SugarTable(\"{className}\", TableDescription = \"{dbTableInfo.Description ?? "表描述"}\")]");
            classContent.AppendLine($"    public partial class {className}");
            classContent.AppendLine("    {");

            // 根据列字段生成属性
            foreach (var column in columns)
            {
                var propertyName = column.DbColumnName;
                var propertyType = MapDbTypeToDotNetType(column.DataType);
                var columnDescription = column.ColumnDescription ?? propertyName;
                var isNullable = column.IsNullable.ToString().ToLower();
                var isPrimaryKey = column.IsPrimarykey.ToString().ToLower();
                var isIdentity = column.IsIdentity.ToString().ToLower();

                classContent.AppendLine($"        /// <summary>");
                classContent.AppendLine($"        /// {columnDescription}");
                classContent.AppendLine($"        /// </summary>");
                classContent.AppendLine($"        [Display(Name = \"{columnDescription}\")]");
                classContent.AppendLine($"        [SugarColumn(ColumnDescription = \"{columnDescription}\", IsNullable = {isNullable}, IsPrimaryKey = {isPrimaryKey}, IsIdentity = {isIdentity})]");
                if (!string.IsNullOrEmpty(isNullable) && propertyType != "string" && propertyType != "object")
                {
                    classContent.AppendLine($"        [Required(ErrorMessage = \"请输入{{0}}\")]");
                }
                if (propertyType == "string" && column.Length > 0)
                {
                    classContent.AppendLine($"        [StringLength({column.Length}, ErrorMessage = \"【{{0}}】不能超过{{1}}字符长度\")]");
                }
                classContent.AppendLine($"        public {propertyType} {propertyName} {{ get; set; }}");
                classContent.AppendLine();
            }

            classContent.AppendLine("    }");
            classContent.AppendLine("}");

            // 生成文件路径
            string filePath = Path.Combine(outputPath, $"{className}.cs");

            // 写入文件
            await File.WriteAllTextAsync(filePath, classContent.ToString());

            return true;
        }

        // 辅助方法：将数据库类型映射到 .NET 类型
        private string MapDbTypeToDotNetType(string dbType)
        {
            switch (dbType.ToLower())
            {
                case "int":
                    return "int";
                case "bigint":
                    return "long";
                case "varchar":
                case "nvarchar":
                case "text":
                    return "string";
                case "datetime":
                    return "DateTime";
                case "bit":
                    return "bool";
                // 添加更多类型映射
                default:
                    return "object";
            }
        }

        #endregion


        #region 

        /// <summary>
        /// DbFirst
        /// </summary>
        /// <param name="className"></param>
        /// <returns></returns>
        public async Task<bool> GenerateRepository(string className)
        {
            string outputPath = @"F:\DbFirst生成\Jst.Repository"; // 指定输出目录

            // 检查目录是否存在，如果不存在则创建
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            string namespaceName = "Jst.Repository";   // 替换为你的命名空间

            // 生成的仓储类内容
            var repositoryClassContent = $@"
using SqlSugar;
using System.Collections.Generic;

namespace {namespaceName} // 请替换为你的命名空间
{{
    public class {className}Repository
    {{
        private readonly DbManager _dbManager;

        public {className}Repository(DbManager dbManager)
        {{
            _dbManager = dbManager;
        }}

        private ISqlSugarClient DbBaseClient => _dbManager.DefaultDb;

        // 获取所有记录
        public List<T> GetAll<T>() where T : class, new()
        {{
            return DbBaseClient.Queryable<T>().ToList();
        }}

        // 根据条件获取单个记录
        public T GetSingle<T>(object id) where T : class, new()
        {{
            return DbBaseClient.Queryable<T>().InSingle(id);
        }}

        // 插入新记录
        public bool Insert<T>(T entity) where T : class, new()
        {{
            var result = DbBaseClient.Insertable(entity).ExecuteCommand();
            return result > 0;
        }}

        // 更新记录
        public bool Update<T>(T entity) where T : class, new()
        {{
            var result = DbBaseClient.Updateable(entity).ExecuteCommand();
            return result > 0;
        }}

        // 删除记录
        public bool Delete<T>(object id) where T : class, new()
        {{
            var result = DbBaseClient.Deleteable<T>(id).ExecuteCommand();
            return result > 0;
        }}
    }}
}}";

            // 确保输出目录存在
            Directory.CreateDirectory(outputPath);

            // 生成文件路径
            var filePath = Path.Combine(outputPath, $"{className}Repository.cs");

            // 生成文件
            await File.WriteAllTextAsync(filePath, repositoryClassContent);

            return true;

        }


        /// <summary>
        /// DbFirst
        /// </summary>
        /// <param name="className"></param>
        /// <returns></returns>
        public async Task<bool> GenerateIRepository(string className)
        {
            string outputPath = @"F:\DbFirst生成\Jst.IRepository"; // 指定输出目录
            // 检查目录是否存在，如果不存在则创建
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            // 生成的仓储接口内容
            var repositoryInterfaceContent = GenerateInterfaceContent(className);

            // 生成文件路径
            var filePath = Path.Combine(outputPath, $"I{className}Repository.cs");

            // 生成文件
            File.WriteAllText(filePath, repositoryInterfaceContent);

            return true;
        }

        /// <summary>
        /// 内容
        /// </summary>
        /// <param name="className">实体类的名称</param>
        /// <returns>生成的接口内容</returns>
        private string GenerateInterfaceContent(string className)
        {
            return $@"
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Jst.IRepository // 自定义命名空间
{{
    /// <summary>
    /// <see cref=""I{className}Repository""/> 接口，用于管理 <see cref=""{className}""/> 实体的持久化操作
    /// </summary>
    public interface I{className}Repository
    {{
        /// <summary>
        /// 异步获取所有 <see cref=""{className}""/> 实体
        /// </summary>
        /// <returns>所有实体的列表</returns>
        Task<List<{className}>> GetAllAsync();

        /// <summary>
        /// 根据ID获取单个 <see cref=""{className}""/> 实体
        /// </summary>
        /// <param name=""id"">实体ID</param>
        /// <returns>匹配的实体</returns>
        Task<{className}> GetByIdAsync(int id);

        /// <summary>
        /// 异步添加 <see cref=""{className}""/> 实体
        /// </summary>
        /// <param name=""item"">待添加的实体</param>
        Task AddAsync({className} item);

        /// <summary>
        /// 异步更新指定的 <see cref=""{className}""/> 实体
        /// </summary>
        /// <param name=""item"">待更新的实体</param>
        Task UpdateAsync({className} item);

        /// <summary>
        /// 异步删除指定ID的 <see cref=""{className}""/> 实体
        /// </summary>
        /// <param name=""id"">待删除的实体ID</param>
        Task DeleteAsync(int id);

        /// <summary>
        /// 根据条件获取 <see cref=""{className}""/> 实体
        /// </summary>
        /// <param name=""predicate"">筛选条件</param>
        /// <returns>匹配的实体列表</returns>
        Task<List<{className}>> GetByConditionAsync(Expression<Func<{className}, bool>> predicate);

        /// <summary>
        /// 异步删除所有 <see cref=""{className}""/> 实体
        /// </summary>


        #endregion


        //-------业务层和接口层活跃性强，不建议生成-----------

        Task DeleteAllAsync();
    }}
}}";

        }
        #endregion




    }
}
